package cn.iocoder.yudao.module.erp.dal.mysql.secstock;

import java.util.*;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.erp.controller.admin.pristock.vo.PriStockRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.stocksmove.vo.SecStockQueryKey;
import cn.iocoder.yudao.module.erp.dal.dataobject.deppurchase.DepPurchaseDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.secstock.SecStockDO;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.erp.controller.admin.secstock.vo.*;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

/**
 * ERP 二级库库存 Mapper
 *
 * @author 芋道源码
 */
@Mapper
public interface SecStockMapper extends BaseMapperX<SecStockDO> {

    default PageResult<SecStockDO> selectPage(SecStockPageReqVO reqVO) {
        return selectPage(reqVO, new LambdaQueryWrapperX<SecStockDO>()
                .eqIfPresent(SecStockDO::getWarehouseId, reqVO.getWarehouseId())
                .eqIfPresent(SecStockDO::getDeptId, reqVO.getDeptId())
                .eqIfPresent(SecStockDO::getProductId, reqVO.getProductId())
                .eqIfPresent(SecStockDO::getProductName,reqVO.getProductName())
                .eqIfPresent(SecStockDO::getProductUnit, reqVO.getProductUnit())
                .eqIfPresent(SecStockDO::getProductStandards, reqVO.getProductStandards())
                .eqIfPresent(SecStockDO::getProductPrice, reqVO.getProductPrice())
                .likeIfPresent(SecStockDO::getProductBatch, reqVO.getProductBatch())
                .likeIfPresent(SecStockDO::getInboundBatch, reqVO.getInboundBatch())
                .likeIfPresent(SecStockDO::getProductUnitName, reqVO.getProductUnitName())
                .likeIfPresent(SecStockDO::getProductCategoryName, reqVO.getProductCategoryName())
                .betweenIfPresent(SecStockDO::getProductValidityDate, reqVO.getProductValidityDate())
                .eqIfPresent(SecStockDO::getCount, reqVO.getCount())
                .eqIfPresent(SecStockDO::getCreator, reqVO.getCreator())
                .betweenIfPresent(SecStockDO::getCreateTime, reqVO.getCreateTime())
                .orderByDesc(SecStockDO::getId));
    }

    List<SecStockDO> getSecStockByDeptId(@Param("type") List<Integer> type, @Param("Sname") String Sname,@Param("rule") String rule,@Param("deptId") Long deptId);

    @Select("SELECT distinct product_batch FROM erp_sec_stock where product_id = #{productId}")
    List<String> selectBatchsByProductId(Long productId);

    @Select("SELECT distinct product_id,product_name,product_standards FROM erp_sec_stock")
    List<SecStockRespVO> selectProductIds();

    @Update("update erp_sec_stock set count = count + #{count} where id = #{id}")
    void updateSecStockCount(SecStockDO productByBatch);

    void updateSecstockCountBatch(@Param("stocksToUpdate") List<SecStockDO> stocksToUpdate);

    List<SecStockDO> selectByBatch(@Param("collect") List<SecStockDO> collect);

    @Select("SELECT distinct product_id FROM erp_sec_stock")
    List<Integer> selectIds();

    @Select("SELECT distinct product_standards FROM erp_sec_stock where product_name = #{productName}")
    List<String> selectStandardsByProductName(String productName);

    @Select("SELECT inbound_batch FROM erp_sec_stock where product_id = #{productId} and product_batch = #{productBatch} ")
    List<String> selectInboundBatchsByProductId(Long productId, String productBatch);

    @Select("SELECT product_id, product_name, product_standards, product_batch, product_unit_id, product_unit_name, product_validity_date, SUM(`count`) AS count " +
            "FROM erp_sec_stock " +
            "GROUP BY product_id, product_name, product_standards, product_batch, product_unit_id, product_unit_name, product_validity_date")
    List<SecStockDO> selectListByBatch();

    @Select("SELECT product_id, product_name, product_standards, product_batch, product_unit_id, product_unit_name, product_validity_date, SUM(`count`) AS count " +
            "FROM erp_sec_stock " +
            "where product_id = #{productId} and product_batch = #{productBatch}"+
            "GROUP BY product_id, product_name, product_standards, product_batch, product_unit_id, product_unit_name, product_validity_date")
    SecStockDO selectByProductIdAndBatch(Long productId, String productBatch);

    @Select("SELECT inbound_batch FROM erp_sec_stock where product_id = #{productId} and product_batch = #{productBatch} and dept_id = #{deptId} order by create_time desc limit 1")
    String selectNewInboundBatch(Long productId, String productBatch, Long deptId);

    @Select("SELECT inbound_batch FROM erp_sec_stock where product_id = #{productId} and product_batch = #{productBatch} and dept_id = #{deptId} order by create_time asc limit 1")
    String selectLastInboundBatch(Long productId, String productBatch, Long deptId);

//    查询对应产品的总库存数
    List<SecStockDO> getSecStockByProductIds(List<Long> productIds, Long deptId);


//    根据出入库规则查询产品
    List<SecStockDO> getSecStockListByProductIds(@Param("productIds") List<Long> productIds,
                                                 @Param("deptId") Long deptId,
                                                 @Param("rule") String rule);

    List<SecStockDO> selectStockListByProductBatch(List<SecStockDO> stocks);

    List<SecStockDO> getStockByDeptAndProductBatchList(@Param("param") List<Map<String, String>> paramList);

    int batchUpdateStockWithVersion(List<SecStockDO> updatedStocks);

    /**
     * 根据产品批次 产品Id 入库批次 查询库存
     * @param queryKeys
     * @return
     */
    List<SecStockDO> selectByBatchIds(List<SecStockQueryKey> queryKeys);

    /**
     * 更新库存  不使用乐观锁版本控制
     * @param updateList
     */
    void updateBatchIgnoreVersion(@Param("list") List<SecStockDO> updateList);
}